import { Button, Table } from "antd";
import "./style.less";
import { useRef } from "react";
import { useSetState } from "ahooks";
import { useState } from "react";
import { nanoid } from "nanoid";

export const ShareScreen = () => {
  const videoRef = useRef<HTMLVideoElement | null>(null);
  const streamRef = useRef<MediaStream | null>(null);
  const [state, setState] = useSetState({
    active: false,
    id: "",
  });
  const [videoTrack, setVideoTrack] = useState<MediaStreamTrack | null>(null);
  // 投屏
  const shareScreen = async () => {
    streamRef.current = await navigator.mediaDevices.getDisplayMedia({
      video: true, // 请求视频轨道
      audio: true, // 请求音频轨道
    });
    // 将获取的流绑定到video元素上
    if (videoRef.current && streamRef.current) {
      videoRef.current.srcObject = streamRef.current;
      setState({ active: streamRef.current.active, id: streamRef.current.id });
      videoRef.current.addEventListener("loadedmetadata", () => {});
      const videoTrack = streamRef.current?.getVideoTracks()?.[0];
      setVideoTrack(videoTrack);
      streamRef.current.onaddtrack = () => {
        console.log(`添加轨道`);
      };
      streamRef.current.onremovetrack = () => {
        console.log(`移除轨道`);
      };
      // @ts-expect-error ignore
      streamRef.current.onactive = () => {
        console.log(`活跃状态`);
      };
      // @ts-expect-error ignore
      streamRef.current.oninactive = () => {
        console.log(`不活跃状态`);
      };
      videoTrack.onmute = () => {
        console.log("静音");
      };
      videoTrack.onunmute = () => {
        console.log("静音");
      };
    }
  };

  // 关闭投屏
  const shareScreenClose = () => {
    if (streamRef.current) {
      // 停止媒体流中的每个轨道
      streamRef.current.getTracks().forEach((track) => {
        track.stop();
      });

      // 从视频元素中移除媒体流
      const videoElement: HTMLVideoElement | null =
        document.querySelector("#videoElement");
      if (videoElement) {
        videoElement.srcObject = null;
      }
      setState({
        active: streamRef?.current?.active,
        id: "",
      });

      // 将 stream 设置为 null，表示屏幕共享已关闭
      streamRef.current = null;
    }
  };

  const removeVideo = () => {
    if (streamRef.current && videoTrack) {
      streamRef.current?.removeTrack(videoTrack);
    }
  };
  const addVideo = () => {
    if (streamRef.current && videoTrack) {
      streamRef.current?.addTrack(videoTrack);
    }
  };

  const watchStreamRef = () => {
    console.log(streamRef.current);
    console.log("tracks", streamRef.current?.getTracks());
  };

  const watchVideoTrack = () => {
    console.log("videoTrack", videoTrack);
  };

  const getConstraints = () => {
    console.log("getConstraints", videoTrack?.getConstraints());
  };

  const columns = [
    {
      title: "Api",
      dataIndex: "api",
      key: "api",
      render: (text: string) => <a>{text}</a>,
    },
    {
      title: "Desc",
      dataIndex: "desc",
      key: "desc",
    },
  ];

  const data = [
    {
      key: "0",
      api: "MediaStream",
      desc: "",
    },
    {
      key: "1",
      api: "属性",
      desc: "",
      children: [
        {
          key: "2",
          api: "active",
          desc: `${state.active} 布尔型。如果这个流处于活动状态值为 true，反之为 false`,
        },
        {
          key: "3",
          api: "id",
          desc: `${state.id} 这是一个包含 36 个字符的 DOMString ，用来作为这个对象的唯一标识符 (GUID) `,
        },
        {
          key: "4",
          api: "ended(只读，废弃)",
          desc: "布尔型。如果 ended 事件在这个对象上触发了，也就是说这个流已经被完全读取，值为 true。如果还没有到达这个流的尾部，值为 false。",
        },
      ],
    },
    {
      key: "5",
      api: "事件处理",
      desc: "",
      children: [
        {
          key: "6",
          api: "MediaStream.onaddtrack",
          desc: "这是 addtrack 事件在这个对象上触发时调用的事件处理器，这时一个MediaStreamTrack对象被添加到这个流。",
        },
        {
          key: "7",
          api: "MediaStream.onended",
          desc: "这是当流终止 ended 时触发的事件。",
        },
        {
          key: "8",
          api: "MediaStream.onremovetrack",
          desc: "这是 removetrack 事件在这个对象上触发事调用的事件处理器，这时一个对象从流上移除",
        },
      ],
    },
    {
      key: "9",
      api: "方法",
      desc: "",
      children: [
        {
          key: "10",
          api: "MediaStream.addTrack()",
          desc: " 存储传入参数 MediaStreamTrack 的一个副本。如果这个轨道已经被添加到了这个媒体流，什么也不会发生; 如果目标轨道为“完成”状态（也就是已经到尾部了），一个 INVALID_STATE_RAISE 异常会产生。",
        },
        {
          key: "11",
          api: "MediaStream.clone()",
          desc: `返回这个 MediaStream 对象的克隆版本。返回的版本会有一个新的 ID。/n返回给定 ID 的轨道。如果没有参数或者没有指定 ID 的轨道，将返回 null。如果有几个轨道有同一个 ID，将返回第一个。`,
        },
        {
          key: "12",
          api: "MediaStream.getTracks()",
          desc: ` 返回流中所有的MediaStreamTrack列表。`,
        },
        {
          key: "13",
          api: "MediaStream.getAudioTracks()",
          desc: ` 返回流中 kind 属性为"audio"的MediaStreamTrack列表。顺序是不确定的，不同浏览器间会有不同，每次调用也有可能不同。`,
        },
        {
          key: "14",
          api: "MediaStream.getTrackById()",
          desc: ` 返回给定 ID 的轨道。如果没有参数或者没有指定 ID 的轨道，将返回 null。如果有几个轨道有同一个 ID，将返回第一个。`,
        },
        {
          key: "15",
          api: "MediaStream.getVideoTracks()",
          desc: `返回流中 kind 属性为"video"的MediaStreamTrack列表。顺序是不确定的，不同浏览器间会有不同，每次调用也有可能不同。`,
        },
        {
          key: "16",
          api: "MediaStream.removeTrack()",
          desc: `移除作为参数传入的 MediaStreamTrack。如果这个轨道不在 MediaStream 对象中什么也不会发生； 如果目标轨道为“完成”状态，一个 INVALID_STATE_RAISE 异常会产生。`,
        },
      ],
    },
    {
      key: nanoid(),
      api: "MediaStreamTrack",
      desc: "",
    },
    {
      key: nanoid(),
      api: "属性",
      desc: "",
      children: [
        {
          key: nanoid(),
          api: "MediaStreamTrack.enabled",
          desc: "布尔值，为 true 时表示轨道有效，并且可以被渲染。为 false 时表示轨道失效，只能被渲染为静音或黑屏。如果该轨道连接中断，该值还是可以被改变但不会有任何效果了。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.id",
          desc: "返回一个由浏览器产生的DOMString类型的 GUID 值，作为这个轨道的唯一标识值。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.kind",
          desc: "返回一个DOMString类型的值。如果为“audio”表示轨道为音频轨道，为“video”则为视频轨道。如果该轨道从它的源上分离，这个值也不会改变。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.label",
          desc: "返回一个DOMString类型。内容为一个用户代理指定的标签，来标识该轨道的来源，比如“internal microphone”。该字符串可以为空，并且在没有源与这个轨道连接的情况下会一直为空。当该轨道从它的源上分离时，这个值也不会改变。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.muted",
          desc: "返回一个布尔类型的值，为 true 时表示轨道是静音，其他为 false。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.readonly",
          desc: "返回一个布尔类型的值，为 true 时表示该轨道是只读的，比如视频文件源或一个被设置为不能修改的摄像头源，或则为 false。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.readyState",
          desc: `返回枚举类型的值，表示轨道的当前状态。该枚举值为以下中的一个：
              "live"表示当前输入已经连接并且在尽力提供实时数据。在这种情况下，输出数据可以通过操作 MediaStreamTrack.enabled 属性进行开关。
              “ended”表示这个输出连接没有更多的数据了，而且也不会提供更多的数据了。`,
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.remote",
          desc: `返回布尔值类型，当为 true 时表示数据是通过RTCPeerConnection提供的，否则为 false。`,
        },
      ],
    },
    {
      key: nanoid(),
      api: "事件处理",
      children: [
        {
          key: nanoid(),
          api: "MediaStreamTrack.onstarted",
          desc: "这是 started 事件在这个对象上被触发时调用的事件处理器，这时一个新的 MediaStreamTrack 对象被添加到轨道源上。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.onmute",
          desc: "这是 mute 事件在这个对象被触发时调用的事件处理器，这时这个流被中断。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.onunmute",
          desc: "这是 unmute 事件在这个对象上被触发时调用的事件处理器，未实现。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.onoverconstrained",
          desc: "这是 overconstrained 事件在这个对象上被触发时调用的事件处理器，未实现。",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.oneended",
          desc: "这是 ended 事件在这个对象被触发时调用的事件处理器，未实现。",
        },
      ],
    },
    {
      key: nanoid(),
      api: "方法",
      children: [
        {
          key: nanoid(),
          api: "MediaStreamTrack.getConstraints()",
          desc: "TBD",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.applyConstraints()",
          desc: "TBD",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.getSettings()",
          desc: "TBD",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.getCapabilities()",
          desc: "TBD",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.clone()",
          desc: "TBD",
        },
        {
          key: nanoid(),
          api: "MediaStreamTrack.stop()",
          desc: "停止播放轨道对应的源，源与轨道将脱离关联，同时轨道状态将设为“ended”。",
        },
      ],
    },
  ];

  return (
    <div className="flex w-[1500px] gap-4">
      <div className="w-[600px]">
        <div className="bg-black w-[500px] h-[420px] flex items-center justify-center">
          <video
            ref={videoRef}
            id="videoElement"
            width="500"
            muted
            autoPlay
            loop
          ></video>
        </div>
        <div className="mt-4 flex justify-start gap-4 flex-wrap">
          <Button
            onClick={() => {
              shareScreenClose();
              shareScreen();
            }}
          >
            投屏
          </Button>
          <Button onClick={shareScreenClose}>关闭投屏</Button>
          <Button onClick={removeVideo}>移除视频轨道</Button>
          <Button onClick={addVideo}>添加视频轨道</Button>
          <Button onClick={watchStreamRef}>查看streamRef</Button>
          <Button onClick={watchVideoTrack}>查看videoTrack</Button>
          <Button onClick={getConstraints}>
            MediaStreamTrack.getConstraints()
          </Button>
        </div>
      </div>
      <div className="w-1/2">
        <Table columns={columns} dataSource={data} pagination={false} />
      </div>
    </div>
  );
};
